package edu.nf.llmtest.service.impl;

import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import edu.nf.llmtest.common.converter.ConversationsConverter;
import edu.nf.llmtest.common.enumeration.RedisKeyEnum;
import edu.nf.llmtest.mapper.ConversationMapper;
import edu.nf.llmtest.model.document.ConversationsDoc;
import edu.nf.llmtest.model.document.SessionDoc;
import edu.nf.llmtest.model.entity.Conversations;
import edu.nf.llmtest.model.entity.Session;
import edu.nf.llmtest.service.ConversationService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @ Author bin
 * @ Create  2025/11/3 上午10:49
 **/
@RequiredArgsConstructor
@Service
public class ConversationServiceImpl implements ConversationService {
    private final ConversationMapper conversationsMapper;
    private final RedisTemplate<String,Object> redisTemplate;
    private final ElasticsearchOperations operations;
    private final ConversationsConverter conversationsConverter;
    @Override
    public List<Conversations> getConversation(String sessionId) {
        List<Conversations> conversationRedis = getConversationRedis(sessionId);
        if (conversationRedis != null){
            return conversationRedis;
        }
        List<Conversations> conversationES = getConversationES(sessionId);
        if (conversationES != null){
            return conversationES;
        }
        return conversationsMapper.getConversationBySessionId(sessionId);
    }

    public List<Conversations> getConversationRedis(String sessionId) {
        List<Conversations> conversations = new ArrayList<>();
        List<Object> range = redisTemplate.opsForList().range(RedisKeyEnum.CONVERSATION_PERFIX.getValue() + sessionId, 0, -1);
        if (range != null){
            for (Object o : range) {
                Conversations conversations1 = (Conversations) o;
                conversations.add(conversations1);
            }
        }
        return conversations;
    }

    public List<Conversations> getConversationES(String sessionId) {
        List<Conversations> ConversationsList = new ArrayList<>();
        NativeQueryBuilder queryBuilder = NativeQuery.builder();
        queryBuilder.withQuery(query ->
                query.bool(bool ->
                        bool.should(
                                QueryBuilders.term(term -> term.field("sessionId").value(sessionId))
                        )
                ));
        //执行查询并返回命中的结果
        SearchHits<ConversationsDoc> hits = operations.search(queryBuilder.build(), ConversationsDoc.class);
        //循环遍历命中的结果集
        hits.getSearchHits().forEach(hit -> {
            ConversationsList.add(conversationsConverter.convertConversations(hit.getContent()));
        });
        return ConversationsList;
    }
}
